package net.towee.model.repo.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import net.towee.model.ProfileArea;
import net.towee.model.ProfileContainer;
import net.towee.model.account.AccountIdentity;
import net.towee.model.discussion.Discussion;
import net.towee.model.impl.ProfileContainerImpl;
import net.towee.model.repo.AttachmentContainer;
import net.towee.model.repo.AttachmentIdentity;
import net.towee.model.repo.DocumentData;
import net.towee.model.repo.DocumentDiff;
import net.towee.model.repo.DocumentIdentity;
import net.towee.model.repo.DocumentNode;
import net.towee.model.repo.TupsContainer;
import net.towee.server.persistence.impl.MongoDbStore;

import com.google.code.morphia.annotations.Entity;
import com.google.code.morphia.annotations.Id;
import com.google.code.morphia.annotations.PostLoad;
import com.google.code.morphia.annotations.Reference;

/**
 * Implementation of DocumentData interface. It should created after
 * DocumentIdentity and have the same ID.
 * 
 * @author c58
 */
@Entity(MongoDbStore.DOCUMENTS_COLLECTION)
public class DocumentDataImpl extends ProfileContainerImpl implements DocumentData, AttachmentContainer,
		TupsContainer {
	@Id
	private String id;

	// TODO:'( very much references, seems bad...
	@Reference
	private DocumentIdentity identity;
	@Reference
	private DocumentNode node;
	@Reference
	private List<AccountIdentity> tups;
	@Reference
	private List<AttachmentIdentity> attach;
	
	// Discussion
	private Discussion discussion;

	private List<DocumentDiff> diffs;
	private String desc;
	
	private Date creationDate;
	private Date updateDate;

	public DocumentDataImpl() {
	}

	public DocumentDataImpl(DocumentIdentity identity, DocumentNode node) {
		this.id = identity.getId();
		this.identity = identity;
		this.node = node;
		this.desc = "";

		this.attach = new ArrayList<AttachmentIdentity>();
		this.diffs = new ArrayList<DocumentDiff>();
		this.profileAreas = new ArrayList<ProfileArea>();
		this.tups = new ArrayList<AccountIdentity>();
	}

	/**
	 * Copy given document data. Only for patching purpose. It means that this
	 * method copy only text, attachments and profile! For other fields it create
	 * references.
	 * 
	 * @param doc
	 */
	public DocumentDataImpl(DocumentData doc) {
		this.id = doc.getIdentity().getId();
		this.identity = doc.getIdentity();
		this.node = doc.getNode();
		this.creationDate = doc.getCreationDate();
		this.updateDate = doc.getUpdateDate();
		this.discussion = doc.getDiscussion();
		this.desc = doc.getDescription();
		this.tups = doc.getTups().getTupsList();
		this.diffs = doc.getDiffs();
		this.attach = new ArrayList<AttachmentIdentity>(doc.getAttachments().getAttachmentList());
		this.profileAreas = new ArrayList<ProfileArea>(doc.getProfile().getProfileAreas());
	}

	@PostLoad
	private void createEmptyFileds() {
		if (attach == null)
			attach = new ArrayList<AttachmentIdentity>();
		if (diffs == null)
			diffs = new ArrayList<DocumentDiff>();
		if(profileAreas == null)
			profileAreas = new ArrayList<ProfileArea>();
		if(tups == null)
			tups = new ArrayList<AccountIdentity>();
	}

	@Override
	public DocumentIdentity getIdentity() {
		return identity;
	}

	@Override
	public List<DocumentDiff> getDiffs() {
		return diffs;
	}

	@Override
	public AttachmentContainer getAttachments() {
		return this;
	}

	@Override
	public Discussion getDiscussion() {
		return discussion;
	}

	@Override
	public DocumentNode getNode() {
		return node;
	}

	@Override
	public TupsContainer getTups() {
		return this;
	}

	@Override
	public ProfileContainer getProfile() {
		return this;
	}

	@Override
	public String getDescription() {
		return desc;
	}

	@Override
	public void setDescription(String desc) {
		this.desc = desc;
	}

	@Override
	public Date getCreationDate() {
		return creationDate;
	}

	@Override
	public Date getUpdateDate() {
		return updateDate;
	}

	@Override
	public void setUpdateDate(Date date) {
		identity.setUpdateDate(date);
		updateDate = date;
	}
	
	@Override
	public void setCreationDate(Date date) {
		identity.setCreationDate(date);
		creationDate = date;
	}

	@Override
	public void removeAttachment(AttachmentIdentity file) {
		attach.remove(file);
	}

	@Override
	public void addAttachment(AttachmentIdentity file) {
		attach.add(file);
	}

	@Override
	public List<AttachmentIdentity> getAttachmentList() {
		return attach;
	}

	@Override
	public boolean contains(AttachmentIdentity att) {
		return attach.contains(att);
	}

	@Override
	public List<AccountIdentity> getTupsList() {
		return tups;
	}

	@Override
	public void addTup(AccountIdentity acc) {
		tups.add(acc);
	}

	@Override
	public void setDiscussion(Discussion disc) {
		this.discussion = disc;
	}

	@Override
	public void setId(String string) {
		this.id = string;
		this.identity.setId(string);
	}

	@Override
	public void setNode(DocumentNode node) {
		this.node = node;
	}

	@Override
	public void setDiffs(List<DocumentDiff> diffs) {
		this.diffs = diffs;
	}
}
